1 module common_windows; 2 3 version(Windows) 4 { 5 pragma(lib, "ole32.lib"); 6 pragma(lib, "oleaut32.lib"); 7 import core.sys.windows.objbase; 8 import core.sys.windows.winbase; 9 import core.sys.windows.windef; 10 import core.sys.windows.com; 11 import core.sys.windows.basetyps; 12 13 import core.stdc.wchar_:wcscmp; 14 import core.sys.windows.oleauto:SysStringLen; 15 import core.sys.windows.wtypes:BSTR; 16 const GUID iid_SetupConfiguration = { 0x177F0C4A, 0x1CD3, 0x4DE7, [ 0xA3, 0x2C, 0x71, 0xDB, 0xBB, 0x9F, 0xA3, 0x6D ] }; 17 18 static interface ISetupInstance : IUnknown 19 { 20 // static const GUID iid = uuid("B41463C3-8866-43B5-BC33-2B0676F7F42E"); 21 static const GUID iid = { 0xB41463C3, 0x8866, 0x43B5, [ 0xBC, 0x33, 0x2B, 0x06, 0x76, 0xF7, 0xF4, 0x2E ] }; 22 23 int GetInstanceId(BSTR* pbstrInstanceId); 24 int GetInstallDate(LPFILETIME pInstallDate); 25 int GetInstallationName(BSTR* pbstrInstallationName); 26 int GetInstallationPath(BSTR* pbstrInstallationPath); 27 int GetInstallationVersion(BSTR* pbstrInstallationVersion); 28 int GetDisplayName(LCID lcid, BSTR* pbstrDisplayName); 29 int GetDescription(LCID lcid, BSTR* pbstrDescription); 30 int ResolvePath(LPCOLESTR pwszRelativePath, BSTR* pbstrAbsolutePath); 31 } 32 33 static interface IEnumSetupInstances : IUnknown 34 { 35 // static const GUID iid = uuid("6380BCFF-41D3-4B2E-8B2E-BF8A6810C848"); 36 37 int Next(ULONG celt, ISetupInstance* rgelt, ULONG* pceltFetched); 38 int Skip(ULONG celt); 39 int Reset(); 40 int Clone(IEnumSetupInstances* ppenum); 41 } 42 43 static interface ISetupConfiguration : IUnknown 44 { 45 // static const GUID iid = uuid("42843719-DB4C-46C2-8E7C-64F1816EFD5B"); 46 static const GUID iid = { 0x42843719, 0xDB4C, 0x46C2, [ 0x8E, 0x7C, 0x64, 0xF1, 0x81, 0x6E, 0xFD, 0x5B ] }; 47 48 int EnumInstances(IEnumSetupInstances* ppEnumInstances) ; 49 int GetInstanceForCurrentProcess(ISetupInstance* ppInstance); 50 int GetInstanceForPath(LPCWSTR wzPath, ISetupInstance* ppInstance); 51 } 52 53 bool detectVSInstallDirViaCOM(out wchar[] versionStr, out wchar[] installStr) 54 { 55 import commons; 56 CoInitialize(null); scope(exit) CoUninitialize(); 57 58 ISetupConfiguration setup; 59 IEnumSetupInstances instances; 60 ISetupInstance instance; 61 DWORD fetched; 62 63 HRESULT hr = CoCreateInstance(&iid_SetupConfiguration, null, CLSCTX_ALL, &ISetupConfiguration.iid, cast(void**) &setup); 64 if(hr != S_OK || !setup) return false; 65 66 scope(exit) setup.Release(); 67 if(setup.EnumInstances(&instances) != S_OK) 68 return false; 69 scope(exit) instances.Release(); 70 71 BSTR thisVersionString, thisInstallDir; 72 while (instances.Next(1, &instance, &fetched) == S_OK && fetched) 73 { 74 import std.conv:to; 75 if(instance.GetInstallationVersion(&thisVersionString) != S_OK || 76 instance.GetInstallationPath(&thisInstallDir) != S_OK) 77 continue; 78 versionStr = thisVersionString[0..SysStringLen(thisVersionString)]; 79 installStr = thisInstallDir[0..SysStringLen(thisInstallDir)]; 80 81 if(!("vsInstallDir" in configs)) 82 { 83 configs["vsInstallDir"] = installStr.to!string; 84 updateConfigFile(); 85 } 86 return true; 87 } 88 return false; 89 } 90 bool detectVSInstallDirViaCOM() 91 { 92 wchar[] vers, install; 93 return detectVSInstallDirViaCOM(vers, install); 94 } 95 }